package com.nhncorp.pleiades.fs;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.hadoop.fs.Path;

import com.nhncorp.pleiades.conf.PleiadesConfiguration;

public abstract class PleiadesFileSystem {
  private static PleiadesFileSystem fs;

  public synchronized static PleiadesFileSystem get(PleiadesConfiguration conf) {
    if (fs != null) {
      return fs;
    }

    try {
      String fileSystem = conf.get("pleiades.filesystem", "local");
      if ("local".equals(fileSystem)) {
        fs = new LocalFileSystem();
      } else if ("hadoop".equals(fileSystem)) {
        fs = new HadoopFileSystem();
      } else {
      }
    } catch (IOException e) {
      e.printStackTrace();
      return null;
    }
    return fs;
  }

  public abstract boolean renameTo(Path targetPath, Path destPath)
      throws IOException;

  public abstract boolean exists(Path path) throws IOException;

  public abstract boolean mkdirs(Path path) throws IOException;

  public abstract Path[] list(Path path) throws IOException;

  public abstract OutputStream create(Path path) throws IOException;

  public abstract InputStream open(Path path) throws IOException;

  public abstract void seek(InputStream in, long offset) throws IOException;

  public abstract boolean delete(Path path) throws IOException;

  public abstract void move(Path targetPath, Path destPath)
      throws IOException;

  public abstract boolean isDirectory(Path path) throws IOException;

  public abstract long getLength(Path path) throws IOException;

  public abstract DataInputStream openDataInputStream(Path path)
      throws IOException;

  public boolean delete(Path path, boolean recursive) throws IOException {
    if (!exists(path)) {
      return true;
    }
    if (isDirectory(path)) {
      Path[] srcs = list(path);
      int length = (srcs != null ? srcs.length : 0);
      for (int i = 0; i < length; i++) {
        if (recursive) {
          if (isDirectory(srcs[i])) {
            if (!delete(srcs[i], recursive)) {
              return false;
            }
          } else {
            if (!delete(srcs[i])) {
              return false;
            }
          }
          // deleteAll(srcs[i], recursive);
        } else {
          if (!delete(srcs[i])) {
            return false;
          }
        }
      }
    }
    if (!delete(path)) {
      return false;
    }

    return true;
  }
}
